package com.xsm.library;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.text.Editable;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;


/**
 * <p>
 * 仿微博实现话题选择输入框
 * </p>
 */
public class TEditText extends android.support.v7.widget.AppCompatEditText {

    private int preTextLength = 0;
    // 默认,话题文本高亮颜色
    private static final int FOREGROUND_COLOR = Color.parseColor("#FF8C00");
    // 默认,话题背景高亮颜色
    private static final int BACKGROUND_COLOR = Color.parseColor("#FFDEAD");

    // 默认,设置重置之后默认文字颜色
    private static final int FOREGROUND_DEFAULT_COLOR = Color.parseColor("#000000");
    // 默认,设置重置之后默认背景颜色
    private static final int BACKGROUND_DEFAULT_COLOR = Color.parseColor("#FFFFFF");

    /**
     * 开发者可设置内容
     */

    // 话题文本高亮颜色
    private int mForegroundColor = FOREGROUND_COLOR;

    // 话题背景高亮颜色
    private int mBackgroundColor = BACKGROUND_COLOR;

    //话题default默认文本颜色
    private int mForegroundDefaultColor = FOREGROUND_DEFAULT_COLOR;
    //话题default默认背景颜色
    private int mBackgroundDefaultColor = BACKGROUND_DEFAULT_COLOR;

    private List<TObject> mTObjectsList = new ArrayList<>();// object集合

    //选中话题的初始位置
    private int selectionTStart = -1;
    //选中的话题
    private String selectionT = "";

    //接口回调
    private TCallBack tCallBack;

    public TEditText(Context context) {
        this(context, null);
        // 初始化设置
        init(context, null);
    }

    public TEditText(Context context, AttributeSet attrs) {
        this(context, attrs, android.support.v7.appcompat.R.attr.editTextStyle);
        init(context, attrs);
    }

    public TEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 初始化设置
        init(context, attrs);
    }

    /**
     * 监听光标的位置,若光标处于话题内容中间则移动光标到话题结束位置
     */
    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);

        if (mTObjectsList == null || mTObjectsList.size() == 0) {
            return;
        }

        int startPosition = 0;
        int endPosition = 0;
        String objectText = "";

        for (int i = 0; i < mTObjectsList.size(); i++) {
            objectText = mTObjectsList.get(i).getObjectText();
            if (getText() != null) {
                int length = objectText.length();

                while (true) {
                    // 获取话题文本开始下标
                    startPosition = getText().toString().indexOf(objectText, startPosition);
                    endPosition = startPosition + objectText.length();
                    if (startPosition == -1) {
                        break;
                    }
                    // 若光标处于话题内容中间则移动光标到话题结束位置
                    if (selStart > startPosition && selStart <= endPosition) {
                        if ((endPosition + 1) > length) {
                            setSelection(endPosition);
                        } else {
                            setSelection(endPosition + 1);
                        }
                        break;
                    }
                    startPosition = endPosition;
                }
            }
        }
    }

    public void setTCallBack(TCallBack callBack) {
        this.tCallBack = callBack;
    }

    /**
     * 初始化
     */
    private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TEditText);
        mBackgroundColor = typedArray.getColor(R.styleable.TEditText_object_background_color, BACKGROUND_COLOR);
        mForegroundColor = typedArray.getColor(R.styleable.TEditText_object_foreground_color, FOREGROUND_COLOR);
        mForegroundDefaultColor = typedArray.getColor(R.styleable.TEditText_object_foreground_default_color, mForegroundDefaultColor);
        mBackgroundDefaultColor = typedArray.getColor(R.styleable.TEditText_object_background_default_color, mBackgroundDefaultColor);
        typedArray.recycle();

        /**
         *
         * 判断是否有选中状态的内容如果有则清除选中
         */
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                refreshSelectionTextColor();
                return false;
            }
        });

        /**
         * 设置点击事件 删除和点击一起判断
         *  首先判断是否有话题须按照农如果存在选中话题则直接清除话题
         *  如果没有选择话题则根据光标的位置进行判断是否需要选中话题并给高亮
         */
        setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {
                    Editable editable = getText();
                    if (editable == null) {
                        return false;
                    }
                    int selectionStart = getSelectionStart();

                    /*
                     * 判断是否有选中话题，如果有选中的话，
                     */
                    if (selectionTStart != -1 && !TextUtils.isEmpty(selectionT)) {
                        // 查询文本是否属于话题对象,若是移除列表数据
                        String tagetText = selectionT;
                        for (int i = 0; i < mTObjectsList.size(); i++) {
                            TObject object = mTObjectsList.get(i);
                            if (tagetText.equals(object.getObjectText())) {
                                mTObjectsList.remove(object);
                                setSelected(false);
                                selectionT = "";
                                selectionTStart = -1;
                                return false;
                            }
                        }
                        return false;
                    }

                    /**
                     * 根据光标的位置判断是否需要选中话题 选中话题之后给高亮
                     */
                    int lastPos = 0;
                    if (mTObjectsList != null && mTObjectsList.size() > 0) {
                        // 遍历判断光标的位置
                        for (int i = 0; i < mTObjectsList.size(); i++) {
                            String objectText = mTObjectsList.get(i).getObjectText();
                            lastPos = getText().toString().indexOf(objectText, lastPos);
                            if (lastPos != -1) {
                                if (selectionStart != 0 && selectionStart >= lastPos && selectionStart <= (lastPos + objectText.length())) {
                                    // 选中话题
                                    selectionTStart = lastPos;
                                    selectionT = objectText;
                                    // 设置背景色（）
                                    editable.setSpan(new BackgroundColorSpan(mBackgroundColor), selectionTStart, lastPos + objectText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                                    setSelected(true);
                                    setSelection(lastPos, lastPos + objectText.length());
                                    return true;
                                }
                                lastPos += objectText.length();
                            }
                        }
                    }
                }
                return false;
            }
        });

        /*
         * 监听软键盘删除按钮(本打算使用setOnKeyListener,但发现在华为手机上Del按钮的keyCode与其他手机不一样,故用此)
         * 1.光标在话题后面,将整个话题内容删除
         * 2.光标在普通文字后面,删除一个字符
         */
        this.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i0, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                //判断是否有话题选中如果有话题选中则直接替换选中话题并重置选中颜色和字体颜色
                refreshTextColor(editable, editable.length());
                //刷新UI内容，
                refreshEditTextUI(editable.toString());

            }
        });
    }

    /**
     * 重置选中内容
     */
    private void refreshTextColor(Editable editable, int length) {
        if (selectionTStart != -1) {
            //重置背景选中颜色
            editable.setSpan(new BackgroundColorSpan(mBackgroundDefaultColor), selectionTStart, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            //重置文字选中颜色
            editable.setSpan(new ForegroundColorSpan(mForegroundDefaultColor), selectionTStart, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            selectionTStart = -1;
            selectionT = "";
        }
    }

    /**
     * 已经选中的清楚选中
     */
    private void refreshSelectionTextColor() {
        showLog(selectionTStart);
        if (getText() != null && !TextUtils.isEmpty(selectionT)) {
            Editable editable = getText();
            if (selectionTStart != -1) {
                //重置背景选中颜色
                editable.setSpan(new BackgroundColorSpan(mBackgroundDefaultColor), selectionTStart, selectionTStart + selectionT.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                //重置文字选中颜色
                editable.setSpan(new ForegroundColorSpan(mForegroundColor), selectionTStart, selectionTStart + selectionT.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                selectionTStart = -1;
                selectionT = "";
            }
        }
    }

    private void showLog(Object tog) {
        Log.e("TAG", "=====>" + tog.toString());
    }

    /**
     * @param content 输入框内容
     */
    private void refreshEditTextUI(String content) {

        /*
         * 内容变化时操作:
         * 1.查找匹配所有话题内容
         * 2.设置话题内容特殊颜色
         */
        if (mTObjectsList.size() == 0)
            return;

        if (TextUtils.isEmpty(content)) {
            mTObjectsList.clear();
            return;
        }

        /*
         * 重新设置span
         */
        Editable editable = getText();
        if (editable == null) {
            return;
        }
        int findPosition = 0;
        for (int i = 0; i < mTObjectsList.size(); i++) {
            final TObject object = mTObjectsList.get(i);
            // 文本
            String objectText = object.getObjectText();
            while (findPosition <= length()) {
                // 获取文本开始下标
                findPosition = content.indexOf(objectText, findPosition);
                if (findPosition != -1) {
                    // 设置话题内容前景色高亮
                    ForegroundColorSpan colorSpan = new ForegroundColorSpan(mForegroundColor);
                    editable.setSpan(colorSpan, findPosition, findPosition + objectText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    findPosition += objectText.length();
                } else {
                    break;
                }
            }

        }
        if (tCallBack != null) {
            preTextLength = content.trim().length();
            tCallBack.onInputLength(preTextLength);
        }
    }

    /**
     * 插入/设置话题
     *
     * @param object 话题对象
     */
    public void setObject(TObject object) {

        if (object == null) {
            return;
        }

        String objectRule = object.getObjectRule();
        String objectText = object.getObjectText();
        if (TextUtils.isEmpty(objectText) || TextUtils.isEmpty(objectRule)) {
            return;
        }

        // 拼接字符# %s #,并保存
        objectText = objectRule + objectText + objectRule;
        object.setObjectText(objectText);

        /*
         * 1.添加话题内容到数据集合
         */
        mTObjectsList.add(object);

        /*
         * 2.将话题内容添加到EditText中展示
         */
        // 光标位置
        int selectionStart = getSelectionStart();
        if (getText() != null) {
            // 原先内容
            Editable editable = getText();

            if (selectionStart >= 0) {
                editable.insert(selectionStart, objectText + " ");
                setSelection(getSelectionStart());// 移动光标到添加的内容后面
            }
        }
    }

    /**
     * 获取object列表数据
     */
    public List<TObject> getObjects() {
        List<TObject> objectsList = new ArrayList<TObject>();
        // 由于保存时候文本内容添加了匹配字符#,此处去除,还原数据
        if (mTObjectsList != null && mTObjectsList.size() > 0) {
            for (int i = 0; i < mTObjectsList.size(); i++) {
                TObject object = mTObjectsList.get(i);
                String objectText = object.getObjectText();
                String objectRule = object.getObjectRule();
                object.setObjectText(objectText.replace(objectRule, ""));// 将匹配规则字符替换
                objectsList.add(object);
            }
        }
        return objectsList;
    }

}
